package main
import "fmt"
import "sync"
// 为什么会发生死锁？goroutine 在退出前调用了 wg.Done() ，程序应该正常退出的。
//原因是 goroutine 得到的 "WaitGroup" 变量是 var wg WaitGroup 的一份拷贝值，
//即 hasaki() 传参只传值。所以哪怕在每个 goroutine 中都调用了 wg.Done()， 主程序中的 wg 变量并不会受到影响。
// 加上& 和 *就没有死锁了
func main() {
    var wg sync.WaitGroup
    done := make(chan struct{})

    workerCount := 2
    for i := 0; i < workerCount; i++ {
        wg.Add(1)
        go hasaki(i, done, &wg)
    }

    close(done)
    wg.Wait()
    fmt.Println("all done!")
}

func hasaki(workerID int, done <-chan struct{}, wg *sync.WaitGroup) {
    fmt.Printf("[%v] is running\n", workerID)
    defer wg.Done()
    <-done
    fmt.Printf("[%v] is done\n", workerID)
}

/*
[1] is running
[1] is done
[0] is running
[0] is done
all done!
*/